干货 | 携程Presto技术演进之路
作者简介
张巍,携程技术中心大数据资深研发工程师。2017年加入携程,在大数据平台部门从事基础框架的研发和运维,目前主要负责 Presto,Kylin,StructedStreaming 等大数据组建的运维,优化,设计及调研工作。对资源调度,OLAP引擎,存储引擎等大数据模块有浓厚的兴趣, 对 hdfs,yarn,presto,kylin,carbondata 等大数据组建有相关优化和改造经验。
一、背景介绍
携程作为中国在线旅游的龙头,提供酒店,机票,度假等服务,这些服务的背后是基于各个部门每天对海量数据的分析。
随着业务的不断增长,用户体验的不断提升,每个部门对数据处理的响应时间要求越来越短,对各个部门报表的响应速度要求越来越快,对跨部门的数据交互和查询也越来越紧密,所以需要一个统一的快速查询引擎,且这个查询引擎需要从GB到PB以上的海量数据集中获取有价值的信息。
我们在技术选型上对比了Presto,Spark,Impala等MPP数据库。综合考量框架本身性能和社区活跃程度,最终选择了Presto。
Presto是Facebook开源的MPP数据库,先简单了解下架构图:
它是一个Master-Slave的架构,由下面三部分组成:
一个Coordinator节点
一个Discovery Server节点
多个Worker节点
Coordinator负责解析SQL语句,生成执行计划,分发执行任务给Worker节点执行。
Discovery Server通常内嵌于Coordinator节点中。
Worker节点负责实际执行查询任务以及负责与HDFS交互读取数据。
Worker节点启动后向DiscoveryServer服务注册,Coordinator从DiscoveryServer获得可以正常工作的Worker节点。如果配置了HiveConnector,需要配置一个Hive MetaStore服务为Presto提供Hive元信息。
二、携程Presto使用的困境
首先来看一下我们2018年前遇到的一些问题。
携程在2014年探索使用Presto去满足用户快速即席查询和报表系统的需求。在2017年末,离线团队接手携程Presto后,发现当时的Presto本身存在一系列问题,那个时候Presto的版本是0.159,也相对较低。
当时用户反馈最多的是,Presto又OOM了。只能采取重启Presto恢复服务,实际上对于用户来说,系统挂掉是最恶劣的一种体验了。
Presto严格的分区类型检查和表类型检查,导致大量用户在Presto上发起的查询以失败告终,对于那些使用老分区重新刷数据的用户简直就是灾难。
一些大数据量的查询经常占用着计算资源,有时运行了2、3个小时,累计生成上百万个split,导致其他小的查询,响应速度受到严重影响。
很早以前,携程在Presto中内部嵌入一个Mysql的驱动, 通过在Mysql表中存放用户账号和密码访问Presto的权限认证。实际上和大数据团队整体使用Kerberos的策略格格不入。
所有的join查询默认都是使用Broadcast join,用户必须指定join模式才能做到Broadcast join 和 Map join的切换。
数据传输过程中并没有做压缩,从而带来网络资源的极大浪费。
Presto自身没有监控分析系统,只能通过Presto自身提供的短时监控页面看到最近几分钟的用户查询记录,对分析和追踪历史错误查询带来很大的不便。
无法知道用户的查询量和用户的查询习惯,从而无法反馈给上游用户有效的信息,以帮助应用层开发人员更合理的使用Presto引擎。
三、携程Presto引擎上所做的改进
为了提供稳定可靠的Presto服务,我们在性能,安全,资源管控,兼容性,监控方面都做了一些改动,以下列出一些主要的改进点。
性能方面
根据Hive statistic信息,在执行查询之前分析hive扫描的数据,决定join查询是否采用Broadcast join还是map join。
Presto Page在多节点网络传输中开启压缩,减少Network IO的损耗,提高分布计算的性能。
通过优化Datanode的存储方式,减少presto扫描Datanode时磁盘IO带来的性能影响。
Presto自身参数方面的优化。
安全方面
启用Presto Kerberos模式,用户只能通过https安全协议访问Presto。
实现Hive Metastore Kerberos Impersonating 功能。
集成携程任务调度系统(宙斯)的授权规则。
实现Presto客户端Kerberos cache模式,简化Kerberos访问参数,同时减少和KDC交互。
资源管控方面
控制分区表最大查询分区数量限制。
控制单个查询生成split数量上限, 防止计算资源被恶意消耗。
自动发现并杀死长时间运行的查询。
兼容性方面
修复对Avro格式文件读取时丢失字段的情况。
兼容通过Hive创建 view,在Presto上可以对Hive view 做查询。(考虑到Presto和Hive语法的兼容性,目前能支持一些简单的view)。
去除Presto对于表字段类型和分区字段类型需要严格匹配的检测。
修复Alter table drop column xxx时出现ConcurrentModification问题。
四、携程Presto升级之路
升级之初Presto 的使用场景如图。
第一阶段,版本升级
对于版本选择,我们关心的几个问题:1)是否很好地解决各类内存泄漏的问题;2)对于查询的性能是否有一定提升。
综上考虑,决定使用0.190版本的Presto作为目标的升级版本。
通过这个版本的升级,结合对Presto的一部分改进,解决了几个主要问题:
Presto内存泄漏问题。
Presto读取Avro文件格式存在字段遗漏的问题。
Presto语法上无法支持整数类型相乘。
第二阶段,权限和性能优化
在第二个版本中,我们主要解决了以下问题:
Kerberos替换Mysql
Join模式的自动感知和切换
限流(拒绝返回100万以上数据量的查询)
认证机制
这里简单介绍下Kerberos权限替换过程中的一些细节。
Presto的认证流程:
Presto 涉及到认证和权限的部分如上面红色框标注的3个部分,Coordinator, HDFS和Hive Metastore这三块。Coordinator和HDFS这两块是比较完善的,重点讲一下Hive Metastore。
在Kerberos模式下,所有SQL都是用Presto的启动账号访问Hive Metastore,比如使用Hive账号启动Presto,不论是flt账户还是htl账户提交SQL,最终到Hive Metastore层面都是Hive账号,这样权限太大,存在安全风险。我们增加了Presto Hive MetastoreImpresonating机制,这样htl在访问Hive Metastore时使用的是通过Hive账号伪装的htl账户。
新的问题又来了,在认证过程中需要获取Hive的Token, 可是Token反复的获取都需要一次Metastore的交互,这样会给Metastore带来压力。于是我们对Token 做了一个缓存,在其Token有效期内缓存在Presto内存中。
第三阶段,资源管控和监控平台
在第三个版本中,我们解决了以下问题:
拦截大量生成split的查询SQL
Presto监控平台初步搭建
限制最大访问的分区数量
数据采集
流程图
程序每一分钟从Presto Coordinator采集数据, 分发到多个监听器,同时写入Mysql表。
当前入库5张监控表。
Basic query:查询基本信息(状态,内存使用,总时间消耗,错误信息等)
Query stats:查询性能信息(每一步的时间消耗,数据输入输出量信息等)
Query info:查询客户端参数信息(发起客户的基本信息,参数信息等)
Query stage info:每个查询中所有stage的信息(输入输出量信息,内存使用情况,调用核的数量等)
Query task info:每个stage中所有task的信息(输入输出信息, 内存信息,调用核数等)
实时健康状况报告
基于以上采集的数据,我们会实时生成presto集群的健康报表以及历史运行趋势。这些数据可以用于:
集群容量的评估
集群健康状态的检测
问题追踪
除了健康报表之外,对于查询错误和性能问题,我们提供了详细的历史数据, 运维人员可以通过报表反应出的异常状况做进一步的排查。
通过报表能够发现某个用户查询时出现了外部异常
通过查看异常堆栈,发现查询是由于hive metastore出现短暂重启引起的查询失败。
其他
在Presto升级改进的同时,我们也调研了Presto on Carbondata的使用场景。
当时Carbondata使用的是1.3.0版本。在此基础上:
修复了一系列Presto on carbon data 的功能和性能的问题
对比了Presto on carbon data 和Presto on hive,得出结论:Presto on Carbon整体性能和Presto on orc的整体性能相当。同样的数据量Carbon snappy的存储是ORC zlib的六倍,就目前存储吃紧的情况下,不适合使用。
目前仅在线上提供Carbondata 连接器,暂未投入业务使用。
当前Presto的架构为:
五、携程Presto未来升级方向
架构完善和技术改进
启用Presto资源队列,规划通过AppName划分每个资源队列的最大查询并发数, 避免某个应用大量的查询并发同时被Presto执行,从而影响其他的App。
实时告警平台,对于错误的查询,Presto能够实时的发送异常查询到告警平台,帮助运维人员快速响应和发现错误以便及时处理。
统一的查询引擎,统一的查询引擎可以在presto,kylin,hive spark-sql之间匹配最优的查询引擎,做语法转换后路由过去。
业务方向
未来携程内部OLAP报表系统(Art Nova) 会更大范围的采用携程Presto作为用户自定义报表的底层查询引擎,以用来提高报表的响应速度和用户体验。
部分业务部门的vdp也计划调研,实时数据计算采用Presto作为其默认的查询引擎的可能性。
下个阶段我们期望的Presto整体架构图:
六、结束语
随着Presto社区的蓬勃发展,最新版本为0.203,其中包含了大量的优化和Bug Fix,希望跟大家一起讨论。
【推荐阅读】